<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017-07-31
 * Time: 12:24
 */
namespace app\api\controller;
use app\models\Models;

class Callback extends Base{
    /**
     * 支付宝异步回调
     * 开始验签，验签方式必须与下单时的签名方式一致
     * 验签通过后核实如下参数out_trade_no、total_amount、seller_id
     * 实现业务逻辑，修改订单支付状态
     * 输出声明,应答支付宝。必须保证本界面无错误。只打印了success，否则支付宝将重复请求回调地址。
     */
    public function asyncCallback(){
        try{
            $params = input('param.');
            $order = new Models('order');
            $info  = $order->_find(['order_no'=>$params['out_trade_no']]);
            // 验证签名
            //self::callbackSign($params,$info);
            // 核实参数
            $info = self::checkParams($params,$info);
            // 开启事务，实现业务逻辑
            $order->startTrans();
            // 添加回调日志
            self::logAdd($params,$info);
            // 支付完成后续业务处理
            self::finishAfter($params,$info);
            // 活动/酒水订单后续业务处理
            if($info['type_id'] == Models::ORDER_TYPE_EVENT || $info['type_id'] == Models::ORDER_TYPE_WINE){
                self::finishAfterTwo($info);
            }
            // 充值订单后续业务处理
            if($info['type_id'] == Models::ORDER_TYPE_RECHARGE){
                self::finishAfterThree($info);
            }
        } catch (\Exception $e){
            $order->rollback();
            return 'fail';
        }
        $order->commit();
        // 输出声明
        return 'success';
    }

    /**
     * 回调验证签名
     * @param $params
     * @param $info
     */
    protected function aliCallbackSign($params,$info){
        if($info['pay_method'] == Models::PAY_ALIPAY){
            $alipay = new AliPay();
            $config = $alipay->config;
            $aop = new \AopClient;
            $aop->alipayrsaPublicKey = $config['publicKey'];  // 请填写支付宝公钥，一行字符串
            //此处验签方式必须与下单时的签名方式一致
            $flag = $aop->rsaCheckV1($params, NULL, "RSA");
            if(!$flag){
                throw new \LogicException('验签失败',1031);
            }
        }
        if($info['pay_method'] == Models::PAY_WECHAT){

        }
    }

    /**
     * 核实参数
     * @param $params
     * @param $info
     * @return string
     */
    protected function checkParams($params,$info){
        if($info && $info['status'] != Models::ORDER_PAY_NOT){
            // 订单支付完成，输出声明
            return 'success';
        }
        if($info['pay_method'] == Models::PAY_ALIPAY){
            if($params['total_amount'] != $info['pay_amount']){
                return 'fail';
            }
        }
        if($info['pay_method'] == Models::PAY_WECHAT){
            if($params['total_fee'] != $info['pay_amount']){
                return 'fail';
            }
        }
    }

    /**
     * 添加回调日志
     * @param $params
     * @param $info
     */
    protected function logAdd($params,$info){
        $data = [];
        if($info['pay_method'] == Models::PAY_ALIPAY){
            $data = [
                'order_amount' => $params['total_amount'],
                'trade_no'     => $params['trade_no'],
                'order_no'     => $params['out_trade_no'],
                'pay_time'     => $params['gmt_payment'],
                'trade_status' => $params['trade_status'],
            ];
        }
        if($info['pay_method'] == Models::PAY_WECHAT){
            $data = [
                'order_amount' => $params['total_fee'],
                'trade_no'     => $params['transaction_id'],
                'order_no'     => $params['out_trade_no'],
                'pay_time'     => $params['time_end'],
                'trade_status' => $params['return_code'],
            ];
        }
        $log = new Models('callback_log');
        $bool = $log->_add($data);
        if(!$bool){
            throw new \LogicException('操作失败',1010);
        }
    }

    /**
     * 支付完成后续业务处理
     * @param $params
     * @param $info
     */
    protected function finishAfter($params,$info){
        $order = new Models('order');
        $trade_no = $info['pay_method'] == Models::PAY_ALIPAY ? $params['trade_no'] : $params['transaction_id'];
        $pay_time = $info['pay_method'] == Models::PAY_ALIPAY ? $params['gmt_payment'] : $params['time_end'];
        // 修改订单信息
        $bool = $order->_save(['trade_no'=>$trade_no,'status'=>Models::ORDER_PAY_YES,'pay_time'=>strtotime($pay_time)],['order_no'=>$params['out_trade_no']]);
        if(!$bool){
            throw new \LogicException('操作失败',1010);
        }
    }

    /**
     * 活动/酒水订单后续业务处理
     * @param $info
     */
    protected function finishAfterTwo($info){
        $account  = new Models('account');
        $business = new Models('business');
        $bool  = true;
        $bool1 = true;
        $bool2 = true;
        if($info['type_id'] == Models::ORDER_TYPE_EVENT){
            $activity = new Models('activity');
            // 筹备活动
            $bool = $activity->_save(['id'=>$info['aid'],'join_num'=>['exp','join_num+1'],'status'=>Models::STATUS_READY]);
            // 用户参加活动关系表添加记录
            $act_join = new Models('activity_join');
            $bool1 = $act_join->_save(['status'=>Models::STATUS_ON],['aid'=>$info['aid'],'uid'=>$info['uid']]);
        }
        if($info['voucher_id']){
            // 如果使用代金券，代金券表添加使用张数
            $voucher = new Models('voucher');
            $bool2 = $voucher->_save(['id'=>$info['voucher_id'],'use_num'=>['exp','use_num+1']]);
        }
        // 更新该销售销售金额
        $bool3 = $account->_save(['sales_amount'=>['exp','sales_amount+'.$info['pay_amount']],'sales_month'=>['exp','sales_month+'.$info['pay_amount']]],['uid'=>$info['sid']]);
        // 更新用户消费金额
        $bool4 = $account->_save(['cost'=>['exp','cost+'.$info['pay_amount']]],['uid'=>$info['uid']]);
        // 商家订单数+1,累加收益金额
        $bool5 = $business->_save(['id'=>$info['bid'],'order_num'=>['exp','order_num+1'],'amount'=>['exp','amount+'.$info['pay_amount']]]);
        if(!$bool || !$bool1 || !$bool2 || !$bool3 || !$bool4 || !$bool5){
            throw new \LogicException('操作失败',1010);
        }
    }

    /**
     * 充值订单后续业务处理
     * @param $info
     */
    protected function finishAfterThree($info){
        $account  = new Models('account');
        $bool = true;
        if($info['sid']){
            // 更新该销售销售金额
            $bool = $account->_save(['sales_amount'=>['exp','sales_amount+'.$info['pay_amount']],'sales_month'=>['exp','sales_month+'.$info['pay_amount']]],['uid'=>$info['sid']]);
        }
        // 获取充值产品的信息
        $product = new Models('recharge_type');
        $pro_info = $product->_find($info['pid']);
        // 更新用户金额
        $bool1 = $account->_save(['recharge'=>['exp','recharge+'.$info['pay_amount']],'coin_balance'=>['exp','coin_balance+'.$pro_info['coin']]],['uid'=>$info['uid']]);
        // 代币记录表添加记录
        $record = new Models('token_record');
        $bool2 = $record->_add(['uid'=>$info['uid'],'coin'=>$pro_info['coin'],'action'=>'充值'.$pro_info['price'].'元','create_time'=>time()]);
        if(!$bool || !$bool1 || !$bool2){
            throw new \LogicException('操作失败',1010);
        }
    }
}